/**
 * Регулярное выражение для проверки соблюдения формата даты DD.MM.YYYY
 */
var CORRECT_DATE_FORMAT = /^(\d{1,2})\.(\d{1,2})\.(\d{4})$/;
/**
 * Регулярное выражение для проверки корректности ввода числа
 */
var CORRECT_NUMBER_FORMAT = /^[1-9]([0-9]*)$/;
/**
 * Регулярное выражение для проверки корректности ввода времени в формате HH:MM
 */
var CORRECT_TIME_FORMAT = /^(([0-1][0-9])|([2][0-3])):([0-5][0-9])$/;
/**
 * Регуляярное выражение для проверки корректности ввода государственного номера автобуса
 */
var CORRECT_STATE_NUMBER = /^([ABEIKMHOPCTX][ABEIKMHOPCTX])\s(\d{4})\-[1-7]$/;
/**
 * Регулярное выражение для проверки корректности ввода года в формате YYYY
 */
var CORRECT_YEAR_FORMAT = /^(\d{4})$/;

//--------------------------------------------------

/**
 * Проверка корректности введённой даты в формате DD.MM.YYYY
 * @param {string} id - идентификатор элемента
 * @param {string} message - текст сообщения об ошибке
 * @return true - введена корректная дата в формате DD.MM.YYYY, false - в противном случае
 */
function isCorrectDate(id, message) {
    var isError = false;
    if(!$(id).val().trim().match(CORRECT_DATE_FORMAT)) {
        showAlert(id, message);
        isError = true;
    } else {
        var datePart = $(id).val().trim().split(".");
        var date = new Date(parseInt(datePart[2]), parseInt(datePart[1]) - 1, parseInt(datePart[0]));
        if (!((datePart[2] == date.getFullYear()) && ((datePart[1] - 1) == date.getMonth()) && (datePart[0] == date.getDate()))) {
            showAlert(id, message);
            isError = true;
        } else {
            markAsSuccessed(id);
        }
    }
    return !isError;
}

/**
 * Проверка корректности введённого числа
 * @param {string} id - идентификатор элемента
 * @param {string} message - текст сообщения об ошибке
 * @return true - введено корректное число, false - в противном случае
 */
function isCorrectNumber(id, message) {
    var isError = false;
    if(!$(id).val().trim().match(CORRECT_NUMBER_FORMAT)) {
        showAlert(id, message);
        isError = true;
    } else {
        markAsSuccessed(id);
    }
    return !isError;
}

/**
 * Проверка корректности введённого времени на соответствие формату HH:MM
 * @param {string} id - идентификатор элемента
 * @param {string} message - текст сообщения об ошибке
 * @return true - введено корректное время в формате HH:MM, false - в противном случае
 */
function isCorrectTime(id, message) {
    var isError = false;
    if(!$(id).val().trim().match(CORRECT_TIME_FORMAT)) {
        showAlert(id, message);
        isError = true;
    } else {
        markAsSuccessed(id);
    }
    return !isError;
}

/**
 * Проверка элемента на заполненность
 * @param {string} id - идентификатор элемента
 * @param {string} message - текст сообщения об ошибке
 * @return true - элемент не пустой, false - пустой
 */
function isNotEmpty(id, message) {
    var isError = false;
    if(!$(id).val().trim()) {
        showAlert(id, message);
        isError = true;
    } else {
        markAsSuccessed(id);
    }
    return !isError;
}

/**
 * Проверка элемента на присутствие выбранного значения
 * @param {string} id - идентификатор элемента
 * @param {string} message - текст сообщения об ошибке
 * @return true - значение выбрано, false - не выбрано
 */
function isChecked(id, message) {
    var isError = false;
    if(!$(id + " :checked").val()) {
        showAlert(id, message);
        isError = true;
    } else {
        markAsSuccessed(id);
    }
    return !isError;
}

/**
 * Проверка элемента на не пустоту выбранного значения
 * @param {string} id - идентификатор элемента
 * @param {string} message - текст сообщения об ошибке
 * @return true - значение не пусто, false - пусто
 */
function isSelected(id, message) {
    var isError = false;
    if($(id).val() == 0) {
        showAlert(id, message);
        isError = true;
    } else {
        markAsSuccessed(id);
    }
    return !isError;
}

/**
 * Проверка корректности ввода государственного номера автобуса
 * @param {string} id - идентификатор элемента
 * @param {string} message - текст сообщения об ошибке
 * @return true - введен корректный государственный номер автобуса, false - в противном случае
 */
function isCorrectStateNumber(id, message) {
    var isError = false;
    if(!$(id).val().trim().match(CORRECT_STATE_NUMBER)) {
        showAlert(id, message);
        isError = true;
    } else {
        markAsSuccessed(id);
    }
    return !isError;
}

/**
 * Проверка корректности введённого года в формате YYYY
 * @param {string} id - идентификатор элемента
 * @param {string} message - текст сообщения об ошибке
 * @return true - введен корректный год в формате YYYY, false - в противном случае
 */
function isCorrectYear(id, message) {
    var isError = false;
    if(!$(id).val().trim().match(CORRECT_YEAR_FORMAT)) {
        showAlert(id, message);
        isError = true;
    } else {
        markAsSuccessed(id);
    }
    return !isError;
}

//--------------------------------------------------

/**
 * Отобразить сообщение об ошибке и выделить блок с ошибкой
 * @param {string} id - идентификатор input'а
 * @param {string} message - текст сообщения об ошибке
 */
function showAlert(id, message) {
    $(id + "HelpInline").text(message);
    $(id + "ControlGroup").removeClass("success");
    $(id + "ControlGroup").addClass("error");
}

/**
 * Скрыть все сообщения об ошибках и корректно заполненных полях
 */
function removeAlerts() {
    $("form").find(".control-group").each(function(index, element) {
        $(element).find(".help-inline").text("");
        $(element).removeClass("success");
        $(element).removeClass("error");
    });
}

/**
 * Пометить поле как корректно заполненное
 * @param {string} id - идентификатор input'а
 */
function markAsSuccessed(id) {
    $(id + "HelpInline").text("\u2713 Correct");
    $(id + "ControlGroup").addClass("success");
    $(id + "ControlGroup").removeClass("error");
}

//--------------------------------------------------

/**
 * Проверить корректность заполнения формы "Пункт расписания"
 * @return true - форма заполнена корректно, false - некорректно
 */
function checkScheduledItem() {
    removeAlerts();

    var res1 = isSelected("#route", "Select route") == true;
    var res2 = isCorrectTime("#departureTime", "Enter correct departure time in HH:MM format") == true;
    var res3 = isCorrectTime("#arrivalTime", "Enter correct arrival time in HH:MM format") == true;
    var res4 = isCorrectTime("#departureTimeFromEndPoint", "Enter correct departure time from end point in HH:MM format") == true;
    var res5 = isCorrectTime("#arrivalTimeToBusTerminal", "Enter correct arrival time to bus terminal in HH:MM format") == true;
    var res6 = isChecked("#routingDays", "Select routing days") == true;
    var res7 = isCorrectNumber("#platformNumber", "Enter correct platform number") == true;

    var departureTime = new Date();
    var arrivalTime = new Date(departureTime.getTime());

    var departureTimeParts = $("#departureTime").val().trim().split(":");
    departureTime.setHours(parseInt(departureTimeParts[0]), parseInt(departureTimeParts[1]));
    var arrivalTimeParts = $("#arrivalTime").val().trim().split(":");
    arrivalTime.setHours(parseInt(arrivalTimeParts[0]), parseInt(arrivalTimeParts[1]));

    if (departureTime.getTime() >= arrivalTime.getTime()) {
        showAlert("#arrivalTime", "Arrival time should be after departure time");
        return false;
    }

    return res1 && res2 && res3 && res4 && res5 && res6 && res7;
}

/**
 * Проверить корректность заполнения формы "Остановочный пункт"
 * @return true - форма заполнена корректно, false - некорректно
 */
function checkStoppingPoint() {
    removeAlerts();

    return isNotEmpty("#stoppingPointName", "Enter stopping point name");
}

/**
 * Проверить корректность заполнения формы "Рейс"
 * @return true - форма заполнена корректно, false - некорректно
 */
function checkTrip() {
    removeAlerts();

    var res1 = isSelected("#route", "Select route") == true;
    var res2 = isSelected("#tripState", "Select trip state") == true;
    var res3 = isCorrectDate("#tripDate", "Enter correct date in DD.MM.YYYY format") == true;
    var res4 = isSelected("#bus", "Select bus") == true;
    var res5 = isNotEmpty("#driverName", "Enter driver name") == true;
    var res6 = isNotEmpty("#conductorName", "Enter conductor name") == true;

    return res1 && res2 && res3 && res4 && res5 && res6;
}

/**
 * Проверить корректность заполнения формы "Автобус"
 * @return true - форма заполнена корректно, false - некорректно
 */
function checkBus() {
    removeAlerts();

    var res1 = isCorrectStateNumber("#stateNumber", "Enter correct state number in LL FFFF-F format") == true;
    var res2 = isSelected("#modelName", "Select model name") == true;
    var res3 = isCorrectYear("#startYearOfExploitation", "Enter correct year in YYYY format") == true;
    var res4 = isSelected("#purposeType", "Select purpose type") == true;

    return res1 && res2 && res3 && res4;
}

/**
 * Проверить корректность заполнения формы "Модель автобуса"
 * @return true - форма заполнена корректно, false - некорректно
 */
function checkBusModel() {
    removeAlerts();

    var res1 = isNotEmpty("#modelName", "Enter model name") == true;
    var res2 = isSelected("#vehicleType", "Select vehicle type") == true;

    return res1 && res2;
}

/**
 * Проверить корректность заполнения формы "Маршрут"
 * @return true - форма заполнена корректно, false - некорректно
 */
function checkRoute() {
    removeAlerts();

    var res1 = isNotEmpty("#routeNumber", "Enter route number") == true;
    var res2 = isNotEmpty("#routeName", "Enter route name") == true;
    var res3 = isSelected("#startPoint", "Select start point") == true;
    var res4 = isSelected("#endPoint", "Select end point") == true;
    var res5 = isChecked("#intermediateStoppingPointsList", "Select intermediate point(s)") == true;
    var res6 = isSelected("#routeType", "Select route type") == true;

    return res1 && res2 && res3 && res4 && res5 && res6;
}

/**
 * Проверить корректность заполнения формы "Пользователь"
 * @return true - форма заполнена корректно, false - некорректно
 */
function checkUser() {
    removeAlerts();

    var res1 = isNotEmpty("#userName", "Enter user name") == true;
    var res2 = isSelected("#userRole", "Select user role") == true;
    var res3 = isNotEmpty("#login", "Enter login") == true;
    var res4 = isNotEmpty("#password", "Enter password") == true;

    return res1 && res2 && res3 && res4;
}

/**
 * Проверить корректность заполнения поля для ввода критерия поиска автобуса по году начала эксплуатации
 * @return true - поле заполнено корректно, false - некорректно
 */
function checkFindBusByStartYearOfExploitation() {
    removeAlerts();
    
    return isCorrectYear("#findBusByStartYearOfExploitation", "Enter correct year in YYYY format");    
}

/**
 * Проверить корректность заполнения поля для ввода критерия поиска автобуса по государственному номеру
 * @return true - поле заполнено корректно, false - некорректно
 */
function checkFindBusByStateNumber() {
    removeAlerts();
    
    return isCorrectStateNumber("#findBusByStateNumber", "Enter correct state number in LL FFFF-F format");    
}

/**
 * Проверить корректность заполнения поля для ввода критерия поиска модели автобуса по названию модели
 * @return true - поле заполнено корректно, false - некорректно
 */
function checkFindBusModelByModelName() {
    removeAlerts();
    
    return isNotEmpty("#findBusModelByModelName", "Enter model name");    
}

/**
 * Проверить корректность заполнения поля для ввода критерия поиска маршрута по названию остановочного пункта
 * @return true - поле заполнено корректно, false - некорректно
 */
function checkFindRouteByStoppingPointName() {
    removeAlerts();
    
    return isNotEmpty("#stoppingPointName", "Enter stopping point name");    
}